package aad.storyboard.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;


import aad.storyboard.model.ActionDownHelper;
import aad.storyboard.model.DragDropHelpCommand;
import aad.storyboard.model.DragHelper;
import aad.storyboard.model.DropHelper;
import aad.storyboard.model.DropListener;
import aad.storyboard.model.DropSpot;
import aad.storyboard.model.Image;
import aad.storyboard.view.GraphicView;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View.OnTouchListener;


/**
 * Handles DragDropAnimations
 */
public class DragDropManager {

	
	private static DragDropManager instance = null;
	private ArrayList<DropSpot> dropZones;
	private OnTouchListener originalTouchListener;
	private GraphicView dragSurface;
	private Image draggedItem;
	private DropSpot activeDropZone;
	
	 private HashMap <Integer, DragDropHelpCommand> commandMap; 

	protected DragDropManager() {		
		dropZones = new ArrayList<DropSpot>();
		commandMap=new HashMap <Integer, DragDropHelpCommand>();
		commandMap.put(0, new ActionDownHelper());
		commandMap.put(1, new DropHelper());
		commandMap.put(2, new DragHelper());		
		
	}
	
	public static DragDropManager getInstance() {
		if (instance == null) {
			instance = new DragDropManager();
		}
		return instance;
	}

	public Context getContext() {
		if (dragSurface == null) 
			return null;
		
		return dragSurface.getContext();
	}
	
	public void init(GraphicView surface) {
		dragSurface = surface;
		clearDropZones();
	}
	

	/**
	 * remove drop spots
	 */
	public void clearDropZones() {
		dropZones.clear();
	}
	
	public void addDropZone(DropSpot dropZone) {
		dropZone.addListner(dropzoneListener);
		dropZones.add(dropZone);
	}


	/**
	 * Register the ViewTouchListener again after the drag and drop has terminated
	 */
	public void setOriginalListener(OnTouchListener listener)
	{
		originalTouchListener=listener;
	}
			

	/**
	 * Check, if the user has dragged the image over a specified drop location and set the color of the drop location
	 */
	public void invalidateDropZones(int x, int y) {		
		if (activeDropZone != null) {
			if (!activeDropZone.isOver(x, y)) {
				activeDropZone.getListener().OnDropSpotLeft(activeDropZone, draggedItem);
				activeDropZone = null;
			}
			else {
				// we are still over the same drop zone, no need to check other drop zones
				return;
			}
		}
		
		for (DropSpot dropZone : dropZones) {
			if (dropZone.isOver(x, y)) {
				activeDropZone = dropZone;
				System.out.println("DropZone found");
				dropZone.getListener().OnDropSpotEntered(activeDropZone, draggedItem);
				break;
			}
		}
	}
	
	public void stoppedDragging() {
		if (activeDropZone != null) {
			activeDropZone.getListener().OnDropped(activeDropZone, draggedItem);
		}
		
		// Registering the "old" listener to the view that initiated this drag session
		dragSurface.setOnTouchListener(originalTouchListener);
		draggedItem = null;
		activeDropZone = null;
	}

	public ArrayList <DropSpot> getDropSpots() {		
		return dropZones;
	}
	

	/**
	 * Command pattern: depending on the action triggered by the user, the corresponding Helper will handle the event 
	 */
	public void handleDragDrop(int action, int X, int Y) {
        DragDropHelpCommand command = commandMap.get(action);
        System.out.println("set x and y in commands");
        
        Iterator myIterator = commandMap.keySet().iterator();
        while(myIterator.hasNext()) {
            Integer key=(Integer)myIterator.next();
            DragDropHelpCommand value=commandMap.get(key);
            value.setX(X);
            value.setY(Y);
        }
        command.help();
	}
	
	public void setDropzoneListener(DropListener dropzoneListener) {
		this.dropzoneListener = dropzoneListener;
	}

	public DropListener getDropzoneListener() {
		return dropzoneListener;
	}


	/**
	 * Instantiates a new DropListner that will set the color of the drop locations if the user dragges the image over this location
	 */
	private DropListener dropzoneListener = new DropListener() {

		@Override
		public void OnDropSpotEntered(DropSpot zone, Image item) {
			Paint p=new Paint();
			p.setColor(Color.YELLOW);
			zone.setPaint(p);
			
			System.out.println("OnDropSpotEntered Yellow");
		}

		@Override
		public void OnDropSpotLeft(DropSpot zone, Image item) {
			Paint p=new Paint();
			p.setColor(Color.TRANSPARENT);
			zone.setPaint(p);
			System.out.println("OnDropSpotLeft Translucent");
		}

		@Override
		public void OnDropped(DropSpot zone, Image item) {
			Paint p=new Paint();
			p.setColor(Color.TRANSPARENT);
			zone.setPaint(p);			
		}
		
	};
	private boolean dragging;
	private Image draggedImage;

	public void setDragging(boolean b) {
		dragging=true;
		
	}

	public void setDraggedImage(Image img) {
		draggedImage=img;		
	}

	public Image getDraggedImage() {		
		return draggedImage;
	}
	
}

